package com.juzipi.demo.realm;


import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;

import java.util.Arrays;

@Slf4j
public class TestCustomerMD5RealmAuthenticator {

    public static void main(String[] args) {
        //创建安全管理器
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        CustomerMD5Realm md5Realm = new CustomerMD5Realm();

        //这是它的一个子类 HashedCredentialsMatcher 哈希凭证匹配器
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");//设置我们用的算法策略，md5加密
        hashedCredentialsMatcher.setHashIterations(1024);//散列的次数
        //设置realm使用hash凭证匹配器
        md5Realm.setCredentialsMatcher(hashedCredentialsMatcher);
        //这样就会先对明文进行加密，然后再用 equals 比较
        securityManager.setRealm(md5Realm);
        //将安全管理器注入安全工具
        SecurityUtils.setSecurityManager(securityManager);
        //通过安全工具类获取subject
        Subject subject = SecurityUtils.getSubject();
        //认证
        UsernamePasswordToken token = new UsernamePasswordToken("guest","guest");
        try {
            subject.login(token);
            log.info("================>>>>>>>>  登陆成功");
        } catch (UnknownAccountException e) {
            log.info("================>>>>>>>>  用户名错误");
            e.printStackTrace();
        } catch (IncorrectCredentialsException e){
            log.info("================>>>>>>>>  密码错误");
            e.printStackTrace();
        }

        //认证的用户进行授权
        if (subject.isAuthenticated()){
            //1.基于单角色的权限控制
            System.out.println(subject.hasRole("admin"));
            //多角色的权限控制,hasAllRoles必须拥有给出的权限列表的所有权限才行
            System.out.println(subject.hasAllRoles(Arrays.asList("admin","user")));
            //是否具有其中一个
            boolean[] booleans = subject.hasRoles(Arrays.asList("admin","user","super"));
            for (boolean aBoolean : booleans) {
                System.out.println(aBoolean);
            }
            System.out.println("-------------------------------------------");
            //基于权限字符串的访问控制  资源标识符：操作：资源类型
            System.out.println("权限: "+subject.isPermitted("user:delete:01"));
            System.out.println("权限: "+subject.isPermitted("student:insert:01"));
            //分别具有哪些权限
            boolean[] permitted = subject.isPermitted("user:*:01", "student:*:01");
            for (boolean b : permitted) {
                System.out.println("分别具有哪些权限: "+ b);
            }
            //同时具有哪些权限
            boolean permittedAll = subject.isPermittedAll("user:*:01","student:*:*");
            System.out.println("同时具有哪些权限: "+permittedAll);

        }

    }


}
